package com.ssb.plugins;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apache.cache.util.Validator;
import com.apache.ius.able.ScheduledExecutor;
import com.apache.ius.plugin.CustomMethodPlugin;
import com.apache.ius.plugin.IusPluginUtil;
import com.apache.tools.DataMap;
import com.apache.tools.DateUtils;
import com.apache.tools.StrUtil;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 黄河接口对接-保单生成通知
 */
@Component
public class HhePolicyMessage extends HheSuperPlugin {

    @Override
    public Object beforeInvoke(Map<String, Object> map) {
        String infoId = String.valueOf(map.get("ssInsurOrder.infoId"));
        if(StrUtil.isNull(infoId)) {
            customMethod(map);//保单生成通知
        } else {//计算分佣
            saveCommissionDetail(infoId);
            map.put(CustomMethodPlugin.pluginInnerReturn,"计算分佣完成");
            map.put(CustomMethodPlugin.resultMark, "T");
        }
        return null;
    }

    @Override
    public Object afterInvoke(Map<String, Object> map) {
        customMethod(map);
        return null;
    }

    private void customMethod(Map<String, Object> map){
        long startLong = System.currentTimeMillis();
        Map<String, Object> param = new HashMap<>();
//        {
//    "jsondata": {
//        "operateType": "2",
//        "policyNo": "66201881133201800011000012",
//        "proposalNo": "06201881133201800011000020",
//        "status": "3"
//    }
//}
        log.info(map);
        boolean mark =false;
        String requestNo = String.valueOf(map.get("proposalNo"));
        if(StrUtil.isNotNull(requestNo)){
            String editSql ="update ss_insur_order set order_status='"+map.get("status")+"', policy_no='"+map.get("policyNo")+"' where request_no='"+requestNo+"' ";
            IusPluginUtil.getInstance().saveInvoke(DATA_SOURCE,editSql);
            mark = true;
            if("3".equals(String.valueOf(map.get("status")))){//成单算分佣
                commissionDetail(requestNo);
               // setPolicyNo(String.valueOf(map.get("policyNo")),requestNo);
            }
        }
        if(mark){
            param.put("success","true");
            param.put("msg","操作成功");
        }else{
            param.put("success","false");
            param.put("msg","操作失败");
        }
        map.put("resultData",param);
        log.info("huanghe interface exetime = "+(System.currentTimeMillis()-startLong)+" ms");
    }

    private void setPolicyNo(final String policyNo, final String requestNo){
        ScheduledExecutor.instance().runable(new Runnable() {
            @Override
            public void run() {
                long startLong = System.currentTimeMillis();
                Map<String, Object> param = new HashMap<>();
                Map<String, Object> head = new HashMap<>();
                Map<String, Object> body = new HashMap<>();
                head.put("platform","SSK");//平台标示（默认与渠道编码一致）
                head.put("requestType","30");//请求类型（10：投保单：30：电子保单；40：保单生成通知，50：电子发票）
                head.put("transactionNo",Validator.generate());//请求事务编号，用于区别是那一次的请求
                head.put("md5Value", "");//32位的编码结果, 另外约定的密码 进行MD5编码 可空
                head.put("timeStamp", DateUtils.Now.fmt_yyyyMMdd_HHmmss());//时间戳
                head.put("errorCode","0000");//0000：成功
                head.put("errorMsg","成功");//错误描述，无异常返回“成功”（默认成功）

                Map<String, Object> inv = new HashMap<>();
                inv.put("policyNo",policyNo);//保单号
                inv.put("errorCode","0000");//0000：成功；
                inv.put("errorMsg","成功");//错误原因,无错误返回“成功”
                List<Map> list = new ArrayList<>();
                list.add(inv);
                body.put("insResults",list);

                param.put("head",head);
                param.put("body",body);
                String str = String.valueOf(sendInterface("Externalcommon/surrenderSSK", param,null));
                log.info("电子保单获取结果："+str);
                if(Validator.isNotNull(str)) {//处理接口返回结果
                    JSONObject json = JSON.parseObject(str).getJSONObject("body");
                    if(json.containsKey("insResults")) {
                        JSONArray array = json.getJSONArray("insResults");
                        for (int i = 0; i < array.size(); i++) {
                            JSONObject obj = array.getJSONObject(i);
                            if ("0000".equals(obj.getString("errorCode"))) {
                                String editSql = "update ss_insur_order set policy_down_url='" + obj.getString("policyDownUrl") + "' where request_no='" + requestNo + "' ";
                                IusPluginUtil.getInstance().saveInvoke(DATA_SOURCE, editSql);
                            }
                        }
                    }
                }
                log.info("huanghe policy_down_url interface exetime = "+(System.currentTimeMillis()-startLong)+" ms");
            }
        });
    }
    /**
     * 计算分佣
     */
    private void commissionDetail(final String requestNo){
        ScheduledExecutor.instance().runable(new Runnable() {
            @Override
            public void run() {
                long startTime = System.currentTimeMillis();
                try {
                    String sql = "select org_id, seller_ename,seller_cname,agent_risk_cname,premium,policy_no,user_owner,pro_id from ss_insur_order where request_no='" + requestNo + "'";
                    List list = select(sql, DATA_SOURCE);
                    if (Validator.isEmpty(list)) {
                        return;
                    }
                    DataMap<String> order = (DataMap) list.get(0);
                    if ("0".equals(order.get("orgId"))) {
                        return;
                    }
                    String checkSql = "select info_id, user_ename from ss_commission_detail where request_no='" + requestNo + "'";
                    List objs = select(checkSql, DATA_SOURCE);
                    List<Map> users = new ArrayList<>();
                    Map user = getUser(order.get("orgId"), order.get("proId"));
                    String orgId = String.valueOf(user.get("orgId"));
                    if (StrUtil.isNotNull(orgId) && !"0".equals(orgId)) {
                        Map obj = getUser(orgId, order.get("proId"));
                        if (!obj.isEmpty()) {
                            buildUser(obj, String.valueOf(obj.get("orgId")), users, objs, order.get("proId"));
                            obj.put("falg", checkUser(objs, String.valueOf(obj.get("userEname"))));
                            obj.put("susbkey", String.valueOf(user.get("relation")));
                            users.add(obj);
                        }
                    }
                    user.put("falg", checkUser(objs, String.valueOf(user.get("userEname"))));
                    users.add(user);
                    String createTime = DateUtils.Now.fmt_yyyyMMdd_HHmmss();
                    String premium = StrUtil.doNull(order.get("premium"), "0");

                    for (int i = 0; i < users.size(); i++) {
                        Map param = new HashMap();
                        Map up = users.get(i);
                        String usbkey = StrUtil.doNull(String.valueOf(up.get("relation")), "0");
                        if (StrUtil.isNotNull(String.valueOf(up.get("susbkey"))) && !order.get("sellerEname").equals(String.valueOf(up.get("userEname")))) {
                            String susbkey = String.valueOf(up.get("susbkey"));
                            usbkey = subtract(usbkey, susbkey, 2);
                        }
                        param.put("ssCommissionDetail.cashOutStatus", "0");
                        param.put("ssCommissionDetail.comScale", usbkey);
                        param.put("ssCommissionDetail.premium", premium);
                        param.put("ssCommissionDetail.userId", up.get("userId"));
                        param.put("ssCommissionDetail.orgId", up.get("orgId"));
                        param.put("ssCommissionDetail.requestNo", requestNo);
                        param.put("ssCommissionDetail.createUser", order.get("sellerEname"));
                        param.put("ssCommissionDetail.userEname", up.get("userEname"));
                        param.put("ssCommissionDetail.userCname", up.get("userCname"));
                        param.put("ssCommissionDetail.policyNo", order.get("policyNo"));
                        param.put("ssCommissionDetail.userOwner", order.get("sellerCname"));//出单人直属渠道商
                        param.put("ssCommissionDetail.applyId", order.get("proId"));//产品ID
                        param.put("ssCommissionDetail.channelName", order.get("agentRiskCname"));//产品名称
                        param.put("ssCommissionDetail.sysName", DateUtils.Now.fmt_yyyyMM());//生成分佣月份
                        param.put("datasource", "ssb");
                        float bl = Float.parseFloat(usbkey) / 100;
                        BigDecimal result3 = new BigDecimal(premium).multiply(new BigDecimal(bl));
                        param.put("ssCommissionDetail.amount", result3.setScale(2, BigDecimal.ROUND_HALF_UP));
                        if ("false".equals(String.valueOf(up.get("falg")))) {
                            param.put("ssCommissionDetail.createTime", createTime);
                            String editSql = "update ss_user_balance set available_balance=available_balance+" + result3.setScale(2, BigDecimal.ROUND_HALF_UP) + " where user_id='" + up.get("userId") + "'";
                            IusPluginUtil.getInstance().saveInvoke(DATA_SOURCE, editSql);
                            IusPluginUtil.getInstance().saveInvoke(DATA_SOURCE, "i_ssCommissionDetail", param);
                        }
                    }
                }catch (Exception e){
                    log.error("生成分佣失败("+requestNo+") ;",e);
                }
                log.info("生成分佣耗时："+(System.currentTimeMillis()-startTime)+" ms");
            }

           /* private void buildUser(Map sobj,String userId,List users,List<Map> objs,String proId){
                if(StrUtil.isNotNull(userId) && !"0".equals(userId)){
                    Map obj = getUser(userId,proId);
                    if(!obj.isEmpty()) {
                       buildUser(obj,String.valueOf(obj.get("orgId")), users,objs,proId);
                       obj.put("falg",checkUser(objs,String.valueOf(obj.get("userEname"))));
                       obj.put("susbkey",String.valueOf(sobj.get("relation")));
                       users.add(obj);
                    }
                }
            }

            private String subtract(String v1,String v2,int scale){
                BigDecimal b1 = new BigDecimal(v1);
                BigDecimal b2 = new BigDecimal(v2);
                BigDecimal bdl = b1.subtract(b2);
                if (new BigDecimal(bdl.intValue()).compareTo(bdl)==0){ //整数
                    return String.valueOf(bdl.intValue());
                }else {//小数
                    return bdl.setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
                }
            }

            private String checkUser(List<Map> objs,String userEname){
                if(!Validator.isEmpty(objs)){
                    for(Map map : objs){
                        if(map.get("userEname").equals(userEname)){
                            return String.valueOf(map.get("infoId"));
                        }
                    }
                }
                return "false";
            }

            private Map getUser(String userId,String proId){//usb_key,user_level
                String sql = "select org_id, user_ename, user_cname,user_id from uct_user where user_id='"+userId+"'";
                List list = (List)IusPluginUtil.getInstance().select("plateform", sql,0,0);
                if(!Validator.isEmpty(list)){
                    String ssOrgProRelation = "select bkge_ratio from ss_org_pro_relation where pro_id='"+proId+"' and user_id ='"+userId+"'";
                    Map relation = selectInfo(ssOrgProRelation,DATA_SOURCE);
                    Map user = (Map)list.get(0);
                    user.put("relation",relation.get("bkgeRatio"));
                    return user;
                }
                return new HashMap(1);
            }*/
        });
    }

    private boolean saveCommissionDetail(String orderId){
        long startTime = System.currentTimeMillis();
        try {
            String sql = "select request_no,org_id, seller_ename,seller_cname,agent_risk_cname,premium,policy_no,user_owner,pro_id from ss_insur_order where info_id='" + orderId + "'";
            List list = select(sql, DATA_SOURCE);
            if (Validator.isEmpty(list)) {
                return false;
            }
            DataMap<String> order = (DataMap) list.get(0);
            if ("0".equals(order.get("orgId"))) {
                return false;
            }
            String checkSql = "select info_id, user_ename from ss_commission_detail where request_no='" + order.get("requestNo") + "'";
            List objs = select(checkSql, DATA_SOURCE);
            List<Map> users = new ArrayList<>();
            Map user = getUser(order.get("orgId"), order.get("proId"));
            String orgId = String.valueOf(user.get("orgId"));
            if (StrUtil.isNotNull(orgId) && !"0".equals(orgId)) {
                Map obj = getUser(orgId, order.get("proId"));
                if (!obj.isEmpty()) {
                    buildUser(obj, String.valueOf(obj.get("orgId")), users, objs, order.get("proId"));
                    obj.put("falg", checkUser(objs, String.valueOf(obj.get("userEname"))));
                    obj.put("susbkey", String.valueOf(user.get("relation")));
                    users.add(obj);
                }
            }
            user.put("falg", checkUser(objs, String.valueOf(user.get("userEname"))));
            users.add(user);
            String createTime = DateUtils.Now.fmt_yyyyMMdd_HHmmss();
            String premium = StrUtil.doNull(order.get("premium"), "0");

            for (int i = 0; i < users.size(); i++) {
                Map param = new HashMap();
                Map up = users.get(i);
                String usbkey = StrUtil.doNull(String.valueOf(up.get("relation")), "0");
                if (StrUtil.isNotNull(String.valueOf(up.get("susbkey"))) && !order.get("sellerEname").equals(String.valueOf(up.get("userEname")))) {
                    String susbkey = String.valueOf(up.get("susbkey"));
                    usbkey = subtract(usbkey, susbkey, 2);
                }
                param.put("ssCommissionDetail.cashOutStatus", "0");
                param.put("ssCommissionDetail.comScale", usbkey);
                param.put("ssCommissionDetail.premium", premium);
                param.put("ssCommissionDetail.userId", up.get("userId"));
                param.put("ssCommissionDetail.orgId", up.get("orgId"));
                param.put("ssCommissionDetail.requestNo", order.get("requestNo"));
                param.put("ssCommissionDetail.createUser", order.get("sellerEname"));
                param.put("ssCommissionDetail.userEname", up.get("userEname"));
                param.put("ssCommissionDetail.userCname", up.get("userCname"));
                param.put("ssCommissionDetail.policyNo", order.get("policyNo"));
                param.put("ssCommissionDetail.userOwner", order.get("sellerCname"));//出单人
                param.put("ssCommissionDetail.applyId", order.get("proId"));//产品ID
                param.put("ssCommissionDetail.channelName", order.get("agentRiskCname"));//产品名称
                param.put("ssCommissionDetail.sysName", DateUtils.Now.fmt_yyyyMM());//生成分佣月份
                param.put("datasource", "ssb");
                float bl = Float.parseFloat(usbkey) / 100;
                BigDecimal result3 = new BigDecimal(premium).multiply(new BigDecimal(bl));
                param.put("ssCommissionDetail.amount", result3.setScale(2, BigDecimal.ROUND_HALF_UP));
                if ("false".equals(String.valueOf(up.get("falg")))) {
                    param.put("ssCommissionDetail.createTime", createTime);
                    String editSql = "update ss_user_balance set available_balance=available_balance+" + result3.setScale(2, BigDecimal.ROUND_HALF_UP) + " where user_id='" + up.get("userId") + "'";
                    IusPluginUtil.getInstance().saveInvoke(DATA_SOURCE, editSql);
                    IusPluginUtil.getInstance().saveInvoke(DATA_SOURCE, "i_ssCommissionDetail", param);
                } else {
                    param.put("ssCommissionDetail.w_infoId", up.get("falg"));
                    param.put("ssCommissionDetail.modifyTime", createTime);
                    IusPluginUtil.getInstance().saveInvoke(DATA_SOURCE, "u_ssCommissionDetail", param);
                }
            }
        }catch (Exception e){
            log.error("生成分佣失败("+orderId+") ;",e);
        }
        log.info("生成分佣耗时："+(System.currentTimeMillis()-startTime)+" ms");
        return true;
    }

    private void buildUser(Map sobj,String userId,List users,List<Map> objs,String proId){
        if(StrUtil.isNotNull(userId) && !"0".equals(userId)){
            Map obj = getUser(userId,proId);
            if(!obj.isEmpty()) {
                buildUser(obj,String.valueOf(obj.get("orgId")), users,objs,proId);
                obj.put("falg",checkUser(objs,String.valueOf(obj.get("userEname"))));
                obj.put("susbkey",String.valueOf(sobj.get("relation")));
                users.add(obj);
            }
        }
    }

    private String subtract(String v1,String v2,int scale){
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        BigDecimal bdl = b1.subtract(b2);
        if (new BigDecimal(bdl.intValue()).compareTo(bdl)==0){ //整数
            return String.valueOf(bdl.intValue());
        }else {//小数
            return bdl.setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
        }
    }

    private String checkUser(List<Map> objs,String userEname){
        if(!Validator.isEmpty(objs)){
            for(Map map : objs){
                if(map.get("userEname").equals(userEname)){
                    return String.valueOf(map.get("infoId"));
                }
            }
        }
        return "false";
    }

    private Map getUser(String userId,String proId){//usb_key,user_level
        String sql = "select org_id, user_ename, user_cname,user_id,usb_key from uct_user where user_id='"+userId+"'";
        List list = (List)IusPluginUtil.getInstance().select("plateform", sql,0,0);
        if(!Validator.isEmpty(list)){
            Map user = (Map)list.get(0);
            String ssOrgProRelation = "select bkge_ratio from ss_org_pro_relation where pro_id='"+proId+"' and user_id ='"+userId+"'";
            Map relation = selectInfo(ssOrgProRelation,DATA_SOURCE);
            if(null==relation || relation.isEmpty()){
                user.put("relation", user.get("usbKey"));
            } else {
                user.put("relation", relation.get("bkgeRatio"));
            }
            return user;
        }
        return new HashMap(1);
    }
}
